#ifndef INFERENCEENGINE_H
#define INFERENCEENGINE_H

#include <QObject>
#include <QStringList>
#include <QList>
#include "rule.h"
#include "rulemanager.h"
#include "factmanager.h"

/**
 * @brief 推理引擎类，用于执行专家系统的推理过程
 * 
 * 该类实现了前向推理机制，能够根据已有事实和规则推导出新的事实，
 * 直到无法推导出更多事实为止。推理过程包括规则匹配、冲突消解等步骤。
 */
class InferenceEngine : public QObject
{
    Q_OBJECT

public:
    /**
     * @brief 构造函数
     * @param ruleManager 规则管理器指针
     * @param factManager 事实管理器指针
     * @param parent 父对象，默认为nullptr
     */
    explicit InferenceEngine(RuleManager *ruleManager, FactManager *factManager, QObject *parent = nullptr);
    
    /**
     * @brief 设置规则管理器
     * @param ruleManager 规则管理器指针
     */
    void setRuleManager(RuleManager *ruleManager);
    
    /**
     * @brief 设置事实管理器
     * @param factManager 事实管理器指针
     */
    void setFactManager(FactManager *factManager);
    
    /**
     * @brief 执行前向推理
     * @return 推导出的结论
     * 
     * 前向推理是一种从已知事实出发，应用规则推导出新事实的方法，
     * 直到无法推导出更多事实为止。
     */
    QString forwardChaining();
    
    /**
     * @brief 查找所有可应用的规则
     * @return 可应用的规则列表
     */
    QList<Rule*> findApplicableRules() const;
    
    /**
     * @brief 冲突消解
     * @param rules 候选规则列表
     * @return 选中的规则
     * 
     * 当多个规则同时可应用时，需要通过冲突消解策略选择一个规则。
     */
    Rule* resolveConflict(const QList<Rule*> &rules) const;
    
    /**
     * @brief 获取推理步骤记录
     * @return 推理步骤列表
     */
    QStringList getInferenceSteps() const;

public slots:
    /**
     * @brief 响应事实添加事件的槽函数
     * @param fact 新添加的事实
     */
    void onFactAdded(const QString &fact);

signals:
    /**
     * @brief 推理步骤信号
     * @param stepDescription 推理步骤描述
     */
    void inferenceStep(const QString &stepDescription);
    
    /**
     * @brief 冲突消解步骤信号
     * @param candidateRuleNames 候选规则名称列表
     * @param selectedRuleName 选中的规则名称
     */
    void conflictResolutionStep(const QStringList &candidateRuleNames, const QString &selectedRuleName);
    
    /**
     * @brief 推理开始信号
     */
    void inferenceStarted();
    
    /**
     * @brief 推理完成信号
     * @param conclusion 推导出的结论
     */
    void inferenceCompleted(const QString &conclusion);
    
    /**
     * @brief 事实添加信号
     * @param fact 添加的事实
     */
    void factAdded(const QString &fact);

private:
    RuleManager *m_ruleManager; ///< 关联规则库
    FactManager *m_factManager; ///< 关联事实库
    QStringList m_inferenceSteps; ///< 推理步骤记录
};

#endif // INFERENCEENGINE_H